package com.gaswell.filter;

import com.gaswell.entity.Roleandperm;
import com.gaswell.pojo.User;
import com.gaswell.service.RoleandpermService;
import com.gaswell.utils.JwtUtils;
import com.gaswell.vo.LoginUser;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * @ClassName JwtAuthenticationTokenFilter
 * @Author xiaow
 * @DATE 2022/9/15 11:03
 **/
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    RoleandpermService roleandpermService;
    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
//获取token
        String token = httpServletRequest.getHeader("token");
//        System.out.println(token);
        if (!StringUtils.hasText(token)) {
//            这里放行就是让其他的过滤器帮我们解决未登录
            filterChain.doFilter(httpServletRequest, httpServletResponse);
//            return是必须的，防止继续进行下面代码
            return;
        }
//        解析token
        String userid = "";

        try {
            Claims claims = JwtUtils.getClaims(token);
            userid = (String) claims.get("userid");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("解析token异常");
        }

//        redis中获取信息
        User o = (User) redisTemplate.opsForValue().get("login" + userid);
        if (Objects.isNull(o)) {
            throw new RuntimeException("token异常");
        }
        List<Roleandperm> byUserId = roleandpermService.getByUserId(new Long(o.getUser_id()));
        List<GrantedAuthority> newList=new LinkedList<>();
        List<String> perms=new LinkedList<>();
        byUserId.forEach(p->{
            SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(p.getPerm());
            newList.add(simpleGrantedAuthority);
            perms.add(p.getPerm());
        });
//        存入SecurityContextgholder，因为后续的过滤器需要在这个东西中找到认证的信息
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(new LoginUser(o,perms), null, newList);
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}
